package org.shaka.cli;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;

/**
 * Hello world!
 *
 */
public class App {
    public static void main(String[] args) throws Exception {
        Map<String, CliProceed> tools = new HashMap<String, CliProceed>();
        tools.put("regular-line-replace", createRegularReplaceByEachLine("regular-line-replace"));

        if (args.length == 0 || !tools.containsKey(args[0])) {
            System.out.printf("please specify one tool of %s%n", tools.keySet());
            return;
        }

        tools.get(args[0]).proceed(Arrays.copyOfRange(args, 1, args.length));
    }

    public static CliProceed createRegularReplaceByEachLine(String toolName) {
        return new RegularReplaceCli(toolName, new StringIOComponent.EachLineStringResource(System.in),
                new StringIOComponent.StringTarget() {
                    @Override
                    public void output(String output) {
                        System.out.println(output);
                    }

                    @Override
                    public void flush() {
                    }
                });
    }

    public static class RegularReplaceCli implements CliProceed {
        private String toolName;
        private StringIOComponent.StringResource resource;
        private StringIOComponent.StringTarget target;

        public RegularReplaceCli(String toolName, StringIOComponent.StringResource resource,
                StringIOComponent.StringTarget target) {
            this.toolName = toolName;
            this.resource = resource;
            this.target = target;
        }

        @SuppressWarnings("static-access")
        @Override
        public void proceed(String... args) throws Exception {
            Options opts = new Options();
            opts.addOption(OptionBuilder.withLongOpt("regular-pattern").withArgName("regular_express_string")
                    .hasArg(true).withDescription("find each line if match regular express pattern").create("g"));
            opts.addOption(OptionBuilder.withLongOpt("replace-content").withArgName("replace_string")
                    .withDescription("replace content if match pattern").hasArg(true).create("r"));
            opts.addOption(OptionBuilder.withLongOpt("encoding").withDescription("input encoding, default is UTF-8")
                    .isRequired(false).create("c"));
            opts.addOption(OptionBuilder.withLongOpt("help").isRequired(false).create("h"));

            CommandLineParser parser = new PosixParser();

            CommandLine cmd = parser.parse(opts, args);
            if (cmd.hasOption("help")) {
                help(toolName, opts, new PrintWriter(System.out));
                return;
            }

            resource.start((cmd.hasOption("encoding")) ? cmd.getOptionValue("encoding") : "UTF-8");

            StringFilterComponent.RegularReplaceFilter filter = new StringFilterComponent.RegularReplaceFilter(
                    cmd.getOptionValue("regular-pattern"), cmd.getOptionValue("replace-content"));

            for (String line : resource) {
                target.output(filter.filter(line));
            }
            target.flush();
        }
    }

    private static void help(String toolName, Options opts, PrintWriter pw) {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp(pw, HelpFormatter.DEFAULT_WIDTH, "shaka cli -> " + toolName, null, opts,
                HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null, false);
        pw.flush();
    }
}
